package com.example.changtest.util

import android.content.ContentResolver
import android.content.Context
import android.database.Cursor
import android.graphics.Bitmap
import android.net.Uri
import android.provider.MediaStore
import android.util.Base64
import java.io.*

const val IMAGE_DIR = "images/"
const val VIDEO_DIR = "videos/"
const val FILE_DIR = "files/"
const val EXTERNAL_IMAGE_DIR = IMAGE_DIR
const val EXTERNAL_VIDEO_DIR = VIDEO_DIR
const val EXTERNAL_FILE_DIR = FILE_DIR

object FileUtils {

    fun getImageDir(context: Context): String {
        val dir = context.filesDir.toString() + "/" + IMAGE_DIR
        File(dir).mkdirs()
        return dir
    }

    fun getVideoDir(context: Context): String {
        val dir = context.filesDir.toString() + "/" + VIDEO_DIR
        File(dir).mkdirs()
        return dir
    }

    /**
     * 除开图片、视频的文件放到这个目录
     */
    fun getFileDir(context: Context): String {
        val dir = context.filesDir.toString() + "/" + FILE_DIR
        File(dir).mkdirs()
        return dir
    }

    fun getExternalImageDir(context: Context): String {
        val dir = context.getExternalFilesDir(null)?.absolutePath + "/" + EXTERNAL_IMAGE_DIR
        File(dir).mkdirs()
        return dir
    }

    fun getExternalVideoDir(context: Context): String {
        val dir = context.getExternalFilesDir(null)?.absolutePath + "/" + EXTERNAL_VIDEO_DIR
        File(dir).mkdirs()
        return dir
    }

    /**
     * 除开图片、视频的文件放到这个目录
     */
    fun getExternalFileDir(context: Context): String {
        val dir = context.getExternalFilesDir(null)?.absolutePath + "/" + EXTERNAL_FILE_DIR
        File(dir).mkdirs()
        return dir
    }
    fun getExternalFileWalletDir(context: Context): String {
        val dir = context.filesDir?.absolutePath + "/" + "wallet/"
        //val dir = context.getExternalFilesDir(null)?.absolutePath + "/" + "wallet/"
        File(dir).mkdirs()
        return dir
    }
    fun getExternalFileDestDir(context: Context): String {
        val dir = context.filesDir?.absolutePath + "/" + "wallet"+ "/" + "keystore"
        //val dir = context.getExternalFilesDir(null)?.absolutePath + "/" + "keystore"
        File(dir).mkdirs()
        return dir
    }

    fun saveBitmapToFile(bitmap: Bitmap, path: String): File? {
        var fos: FileOutputStream? = null
        val file: File?
        try {
            file = File(path)
            fos = FileOutputStream(file)
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos)
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        } finally {
            fos?.flush()
            fos?.close()
        }
        return file
    }

    fun getImageFilePathFromUri(context: Context, uri: Uri): String? {
        val scheme = uri.scheme
        var data: String? = null
        when (scheme) {
            null -> data = uri.path
            ContentResolver.SCHEME_FILE -> data = uri.path
            ContentResolver.SCHEME_CONTENT -> {
                var cursor: Cursor? = null
                try {
                    cursor = context.contentResolver.query(
                        uri,
                        arrayOf(MediaStore.Images.ImageColumns.DATA),
                        null,
                        null,
                        null
                    )
                    cursor?.run {
                        if (moveToFirst()) {
                            val index = getColumnIndex(MediaStore.Images.ImageColumns.DATA)
                            if (index > -1) {
                                data = getString(index)
                            }
                        }
                    }
                } finally {
                    cursor?.close()
                }
            }
        }
        return data
    }

    fun readInputStreamToFile(inputStream: InputStream, path: String): File? {
        var fos: FileOutputStream? = null
        val file: File?
        try {
            file = File(path)
            fos = FileOutputStream(file)
            val byteArray = ByteArray(4096)
            while (true) {
                val read: Int = inputStream.read(byteArray)
                if (read == -1) {
                    break
                }
                fos.write(byteArray, 0, read)
            }
            fos.flush()
        } catch (e: IOException) {
            e.printStackTrace()
            return null
        } finally {
            inputStream.close()
            fos?.close()
        }
        return file
    }

    fun file2Base64(path: String): String? {
        var inputStream: InputStream? = null
        val base64: String?
        try {
            inputStream = FileInputStream(path)
            val byteArray = ByteArray(inputStream.available())
            inputStream.read(byteArray)
            base64 = Base64.encodeToString(byteArray, Base64.DEFAULT)
        } catch (e: IOException) {
            e.printStackTrace()
            return null
        } finally {
            inputStream?.close()
        }
        return base64
    }

    /**
     * 判断目录是否存在，不存在则判断是否创建成功
     *
     * @param file 文件
     * @return `true`: 存在或创建成功<br></br>`false`: 不存在或创建失败
     */
    fun createOrExistsDir(file: File?): Boolean {
        // 如果存在，是目录则返回true，是文件则返回false，不存在则返回是否创建成功
        return file != null && if (file.exists()) file.isDirectory else file.mkdirs()
    }

    fun writeFileFromLineString(file: File?, content: String?, append: Boolean): Boolean {
        if (file == null || content == null) return false
        if (!createOrExistsDir(file)) return false
        var bw: BufferedWriter? = null
        return try {
            bw = BufferedWriter(FileWriter(file, append))
            bw.write(content)
            bw.newLine()
            true
        } catch (e: IOException) {
            e.printStackTrace()
            false
        } finally {
            bw?.close()
        }
    }
}